package com.hb.trade.api.routine.controller.center.au;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hb.core.pojo.RoleDataAuthEntity;
import com.hb.core.pojo.UserConfig;
import com.hb.core.pojo.center.au.dto.*;
import com.hb.core.pojo.center.au.entity.Org;
import com.hb.core.pojo.center.au.entity.User;
import com.hb.core.pojo.center.au.entity.UserVerify;
import com.hb.core.pojo.center.au.vo.UnConfirmUserInfoVo;
import com.hb.core.pojo.constant.Constants;
import com.hb.core.pojo.enums.RoleSignEnum;
import com.hb.core.pojo.enums.RoleTypeEnum;
import com.hb.core.pojo.parent.PageResult;
import com.hb.trade.api.routine.util.RoleDataAuthUtil;
import com.hb.trade.client.center.OrgClient;
import com.hb.trade.client.center.OrgDeptClient;
import com.hb.trade.client.center.RoleClient;
import com.hb.trade.client.center.UserClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.fzzn.core.auth.shiro.util.CredentialUtil;
import org.fzzn.core.auth.shiro.util.ShiroUtil;
import org.fzzn.core.cache.redis.StringRedisService;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.model.user.login.LoginUser;
import org.fzzn.core.util.MsgUtil;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统用户相关
 */
@Slf4j
@Version(1.0)
@Api(tags = {"用户信息管理"})
@RequestMapping("/{version}")
@RestController
public class ApiUserController {

    protected final UserClient userClient;
    protected final OrgClient orgClient;
    protected final RoleClient roleClient;
    protected final StringRedisService redisService;
    protected final OrgDeptClient orgDeptClient;

    public ApiUserController(UserClient userClient,
                             OrgClient orgClient,
                             RoleClient roleClient,
                             StringRedisService redisService,
                             OrgDeptClient orgDeptClient) {
        this.userClient = userClient;
        this.orgClient = orgClient;
        this.roleClient = roleClient;
        this.redisService = redisService;
        this.orgDeptClient = orgDeptClient;
    }

    /**
     * 用户列表信息，带分页
     * 20220425 该接口查询的用户必须与当前登录用户的角色一致
     *
     * @return
     */
    @ApiOperation(value = "用户列表信息(返回分页对象)", notes = "用户列表信息(返回分页对象)")
    @PostMapping("/user/pageUsers")
    public ResponseDto<?> pageUsers(@RequestBody UserDTO userDTO) {
/*        Long orgId = userDTO.getOrgId();
        // 查询当前企业以及分公司下的用户列表
        if (Integer.valueOf(1).equals(userDTO.getType())) {
            //判断一下前端页面传过来的是否是当前企业的父企业
            Message<List<OrgDTO>> listMessage = orgClient.listParent(ShiroUtil.getOrgId());

            if (listMessage.isFail()) {
                return ResultUtil.FAIL;
            }
            if (CollUtil.isNotEmpty(listMessage.getData())) {
                List<Long> parentOrgIdList = listMessage.getData().stream().map(Org::getId).collect(Collectors.toList());
                //如果前端传过来的是父级企业只查询当前登录账号企业下面的部门
                orgId = CollUtil.contains(parentOrgIdList, orgId) ? ShiroUtil.getOrgId() : orgId;
            }

        } else {
            // 查询当前企业的用户列表
            userDTO.setOrgId(ShiroUtil.getOrgId());
        }*/

        // 设置当前用户的业务角色标识, 当前登录用户是什么角色就只显示什么角色的用户信息
        JSONObject extInfo = ShiroUtil.getExtInfo();
        Integer roleSign = extInfo.getInt("roleSign");
        userDTO.setRoleSign(roleSign);

        // 数据权限查询条件
        RoleDataAuthEntity roleDataAuthEntity = RoleDataAuthUtil.buildDataAuth();
        userDTO.setDataAuth(roleDataAuthEntity);

        Message<PageResult<UserDTO>> pageUserMsg = userClient.pageUsers(userDTO);
        if (pageUserMsg.isSuccess()) {
            return ResultUtil.msg(pageUserMsg);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 获取用户列表
     * 参数支持orgId, deptId
     * orgId查询指定企业下的用户列表
     * deptId查询指定部门下的用户列表
     * 当两个参数都为null时, 默认取当前登录用户所在企业的所有用户
     *
     * @param userDTO
     * @return
     */
    @ApiOperation(value = "当前登录用户所在企业的用户列表", notes = "当前登录用户所在企业的用户列表")
    @PostMapping("/user/currentListUsers")
    public ResponseDto currentListUsers(@RequestBody UserDTO userDTO) {
        if (userDTO.getOrgId() == null && userDTO.getDeptId() == null) {
            Long orgId = ShiroUtil.getOrgId();
            userDTO.setOrgId(orgId);
        }
        Message<List<User>> listMessage = userClient.listUsers(userDTO);
        return ResultUtil.msg(listMessage);
    }

    /**
     * 新增一个用户
     *
     * @return
     */
    @ApiOperation(value = "新增一个用户", notes = "新增一个用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orgId", value = "所属企业ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "deptId", value = "企业下的部门ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "phone", value = "手机号码", dataTypeClass = String.class),
            @ApiImplicitParam(name = "username", value = "登录用户名", dataTypeClass = String.class),
            @ApiImplicitParam(name = "fullName", value = "姓名", dataTypeClass = String.class),
            @ApiImplicitParam(name = "email", value = "个人邮箱", dataTypeClass = String.class),
            @ApiImplicitParam(name = "userType", value = "用户类型(只能是2或者3, 企业管理员或普通用户)", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "userStatus", value = "用户状态(1: 正常, 2: 禁用)", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "roleIds", value = "角色ID列表", dataTypeClass = List.class)
    })
    @PostMapping("/user/newUser")
    public ResponseDto<?> newUser(@RequestBody UserDTO userDTO) {
        String paramsValid = userDTO.paramsValid();
        if (StrUtil.isNotEmpty(paramsValid)) {
            return ResultUtil.fail(paramsValid);
        }
        Long userId = ShiroUtil.getUserId();


        // 设置密码
        userDTO.setSaltSource(UserDTO.INIT_SALT_VALUE);
        String password = userDTO.getPassword();
        String md5 = CredentialUtil.md5(password, userDTO.getSaltSource());
        userDTO.setPassword(md5);
        // 设置操作人ID
        userDTO.buildBaseData(1, ShiroUtil.getUsername(), userId);
        UserConfig userConfig = new UserConfig();
        userConfig.setCanCreateBranchCompany(2);
        userDTO.setUserConfig(userConfig);


        // 判断参数中的角色是否包含分公司管理员
        Long branchManagerId = roleClient.hasRoleType(userDTO.getRoleIds(), RoleTypeEnum.BRANCH_COMPANY_MANAGER);
        if (branchManagerId != null) {
            // 查询指定企业下有没有分公司管理员的角色用户
            RoleDTO param = new RoleDTO();
            param.setId(branchManagerId);
            param.setPageFlag(2);
            param.setOrgId(userDTO.getOrgId());
            param.setRoleSign(ShiroUtil.getExtInfoInt("roleSign"));
            Message<RoleDTO> roleDTOMessage = roleClient.membersByRole(param);
            RoleDTO data = roleDTOMessage.getData();
            Object users = data.getUsers();
            if (CollUtil.isNotEmpty(JSONUtil.parseArray(users))) {
                return ResultUtil.fail("该企业下已存在分公司管理员");
            }
        }

        Message<Boolean> message = userClient.addSystemUser(userDTO);
        if (message.isFail()) {
            return ResultUtil.error(message.getMessage());
        }
        //2022-4-30 判断企业认证方式已修改，不需要复制信息
        //获取一级用户的认证信息并且设置一级用户信息
//        User verifyUser = new User();
//        verifyUser.setId(userId);
//        Message<UserVerify> verifyMessage = userClient.getUserVerifyByUserId(verifyUser);
//        if (verifyMessage.getData() == null) {
//            return ResultUtil.msg(message);
//        }
//        UserVerify parentVerify = verifyMessage.getData();
//        UserVerify verify = new UserVerify();
//        verify.buildBaseData(1);
//        verify.setUserId(userDTO.getId());
//        verify.setVerifyType(parentVerify.getVerifyType());
//        verify.setAuditStatus(parentVerify.getAuditStatus());
//        userClient.saveVerifyByZapp(verify);

        return ResultUtil.msg(message);

    }

    /**
     * 更新用户信息
     *
     * @return
     */
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息(仅更新用户信息)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "数据ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orgId", value = "所属企业ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "deptId", value = "企业下的部门ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "phone", value = "手机号码", dataTypeClass = String.class),
            @ApiImplicitParam(name = "fullName", value = "姓名", dataTypeClass = String.class),
            @ApiImplicitParam(name = "email", value = "个人邮箱", dataTypeClass = String.class),
            @ApiImplicitParam(name = "userConfig", value = "用户配置", dataTypeClass = JSONObject.class)
    })
    @PostMapping("/user/updateUserInfo")
    public ResponseDto<?> updateUserInfo(@RequestBody UserDTO userDTO) {
        // 设置操作人ID
        userDTO.setUpdateId(ShiroUtil.getUserId());

        Message<Boolean> message = userClient.updateUser(userDTO);
        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 更新用户角色
     *
     * @return
     * @see ApiUserController#updateUserInfoAndRoles(UserDTO)
     * @deprecated
     */
    @ApiOperation(value = "更新用户角色", notes = "更新用户角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = List.class),
            @ApiImplicitParam(name = "roleIds", value = "角色ID列表", dataTypeClass = List.class)
    })
    @PostMapping("/user/updateUserRoles")
    @Deprecated
    public ResponseDto<?> updateUserRoles(@RequestBody UserDTO userDTO) {
        // 判断参数中的角色是否包含分公司管理员
        Long branchManagerId = roleClient.hasRoleType(userDTO.getRoleIds(), RoleTypeEnum.BRANCH_COMPANY_MANAGER);
        if (branchManagerId != null) {
            // 查询指定企业下有没有分公司管理员的角色用户
            RoleDTO param = new RoleDTO();
            param.setId(branchManagerId);
            param.setPageFlag(2);
            param.setOrgId(userDTO.getOrgId());
            Message<RoleDTO> roleDTOMessage = roleClient.membersByRole(param);
            RoleDTO data = roleDTOMessage.getData();
            Object users = data.getUsers();
            if (CollUtil.isNotEmpty(JSONUtil.parseArray(users))) {
                return ResultUtil.fail("该企业下已存在分公司管理员");
            }
        }
        Message<Boolean> updateMsg = userClient.updateUserRoles(userDTO);
        return ResultUtil.msg(updateMsg);
    }

    /**
     * 更新用户信息和角色
     *
     * @return
     */
    @ApiOperation(value = "更新用户信息及其角色", notes = "更新用户信息和角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = List.class),
            @ApiImplicitParam(name = "orgId", value = "所属企业ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "deptId", value = "企业下的部门ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "phone", value = "手机号码", dataTypeClass = String.class),
            @ApiImplicitParam(name = "fullName", value = "姓名", dataTypeClass = String.class),
            @ApiImplicitParam(name = "email", value = "个人邮箱", dataTypeClass = String.class),
            @ApiImplicitParam(name = "roleIds", value = "角色ID列表", dataTypeClass = List.class)
    })
    @PostMapping("/user/updateUserInfoAndRoles")
    public ResponseDto<?> updateUserInfoAndRoles(@RequestBody UserDTO userDTO) {
        String password = userDTO.getPassword();
        if (StrUtil.isNotEmpty(password)) {
            if (StrUtil.startWith(password, "*")) {
                userDTO.setPassword(null);
            } else {
                String newPassword = CredentialUtil.md5(userDTO.getPassword(), UserDTO.INIT_SALT_VALUE);
                userDTO.setPassword(newPassword);
            }
        }
        // 判断参数中的角色是否包含分公司管理员
        Long branchManagerId = roleClient.hasRoleType(userDTO.getRoleIds(), RoleTypeEnum.BRANCH_COMPANY_MANAGER);
        if (branchManagerId != null) {
            // 查询指定企业下有没有分公司管理员的角色用户
            RoleDTO param = new RoleDTO();
            param.setId(branchManagerId);
            param.setOrgId(userDTO.getOrgId());
            param.setPageFlag(2);
            Message<RoleDTO> roleDTOMessage = roleClient.membersByRole(param);
            RoleDTO data = roleDTOMessage.getData();
            Object users = data.getUsers();
            JSONArray usersJson = JSONUtil.parseArray(users);
            List<User> userList = JSONUtil.toList(usersJson, User.class);
            userList = userList.stream().filter(item -> !item.getId().equals(userDTO.getId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(userList)) {
                return ResultUtil.fail("该企业下已存在分公司管理员");
            }
        }
        // 设置操作人ID
        userDTO.setUpdateId(ShiroUtil.getUserId());
        Message<Boolean> message = userClient.updateUser(userDTO);
        return ResultUtil.msg(message);
    }

    /**
     * 重置用户密码
     *
     * @return
     */
    @ApiOperation(value = "重置用户密码", notes = "重置用户密码, 密码重置为 " + UserDTO.INIT_PASSWORD + ", 接口返回成功后将删除该用户的登录状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = List.class)
    })
    @PostMapping("/user/resetUserPass")
    public ResponseDto resetUserPass(@RequestBody UserDTO userDTO) {
        userDTO.setPassword(CredentialUtil.md5(UserDTO.INIT_PASSWORD, UserDTO.INIT_SALT_VALUE));
        Message<Boolean> resetMsg = userClient.resetUserPass(userDTO);
        if (resetMsg.isSuccess()) {

            // 用户下线
            Message<User> clientUser = userClient.getByUserId(userDTO.getId());
            if (clientUser.isSuccess()) {
                ShiroUtil.offline(clientUser.getData().getUsername(), userDTO.getId());
            }
        }
        return ResultUtil.msg(resetMsg);
    }

    /**
     * 绑定介质CA
     *
     * @return
     */
    @ApiOperation(value = "绑定介质CA", notes = "绑定介质CA")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "caId", value = "介质CA唯一标识", dataTypeClass = String.class)
    })
    @PostMapping("/user/bindCA")
    public ResponseDto bindCA(@RequestBody UserDTO userDTO) {
        UserDTO user = new UserDTO();
        user.setId(userDTO.getId());
        //TODO
//        user.setCaId(userDTO.getCaId());

        Message<Boolean> message = userClient.updateUser(user);

        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 解绑介质CA
     *
     * @return
     */
    @ApiOperation(value = "解绑介质CA", notes = "解绑介质CA")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = Long.class)
    })
    @PostMapping("/user/unbindCA")
    public ResponseDto unbindCA(@RequestBody UserDTO userDTO) {
        //todo
//        userDTO.setCaId("-1");
        return bindCA(userDTO);
    }

    /**
     * 启用指定用户
     *
     * @return
     */
    @ApiOperation(value = "启用指定用户", notes = "启用指定用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = Long.class)
    })
    @PostMapping("/user/enableUser")
    public ResponseDto enableUser(@RequestBody UserDTO userDTO) {
        UserDTO user = new UserDTO();
        user.setId(userDTO.getId());
        user.setUserStatus(1);

        Message<Boolean> message = userClient.updateUser(user);

        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 禁用指定用户
     *
     * @return
     */
    @ApiOperation(value = "禁用指定用户", notes = "禁用指定用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataTypeClass = Long.class)
    })
    @PostMapping("/user/disableUser")
    public ResponseDto disableUser(@RequestBody UserDTO userDTO) {
        UserDTO user = new UserDTO();
        user.setId(userDTO.getId());
        user.setUserStatus(2);

        Message<Boolean> message = userClient.updateUser(user);

        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 拉黑指定用户或者企业
     *
     * @return
     */
    @ApiOperation(value = "拉黑指定用户或者企业", notes = "拉黑指定用户或者企业")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orgId", value = "企业ID", dataTypeClass = Long.class)
    })
    @PostMapping("/user/pushToBlackList")
    public ResponseDto pushToBlackList(@RequestBody UserBlacklistDTO userBlack) {
        if (userBlack.getUserId() != null && userBlack.getOrgId() != null) {
            return ResultUtil.fail("userId 与 orgId 不能同时存在");
        }
        Message<Boolean> message = userClient.pushToBlackList(userBlack);
        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 取消拉黑指定用户或者企业
     *
     * @return
     */
    @ApiOperation(value = "取消拉黑指定用户或者企业", notes = "取消拉黑指定用户或者企业")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "orgId", value = "企业ID", dataTypeClass = Long.class)
    })
    @PostMapping("/user/pullOutOfBlackList")
    public ResponseDto pullOutOfBlackList(@RequestBody UserBlacklistDTO userBlack) {
        if (userBlack.getUserId() != null && userBlack.getOrgId() != null) {
            return ResultUtil.fail("userId 与 orgId 不能同时存在");
        }
        Message<Boolean> message = userClient.pullOutOfBlackList(userBlack);

        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 删除一个用户
     *
     * @return
     */
    @ApiOperation(value = "删除一个用户", notes = "删除一个用户")
    @PostMapping("/user/removeUser")
    public ResponseDto removeUser(@RequestBody UserDTO user) {
        // 发送企业管理员短信验证
        // ...

        Message<Boolean> message = userClient.removeUser(user);
        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }

    /**
     * 保存用户信息
     * 基于中招APP扫码之后的数据
     *
     * @return
     */
    @ApiOperation(value = "保存用户信息(基于中招APP扫码之后的数据)", notes = "保存用户信息(基于中招APP扫码之后的数据)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleSign", value = "用户角色标识", dataTypeClass = Integer.class)
    })
    @PostMapping("/user/saveZappUser")
    public ResponseDto saveZappUser(@RequestBody ZappUserDTO zappUser) {
        Message<Boolean> message = userClient.saveZappUser(zappUser);
        if (message.isSuccess()) {
            return ResultUtil.msg(message);
        }
        return ResultUtil.FAIL;
    }


    /**
     * 修改密码
     *
     * @param userDTO
     * @return org.fzzn.core.model.msg.ResponseDto
     * @author tian
     * @date 2022-2-23 18:13
     */
    @ApiOperation(value = "修改密码", notes = "修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "用户当前密码", dataTypeClass = String.class),
            @ApiImplicitParam(name = "newPassword", value = "用户新密码", dataTypeClass = String.class)
    })
    @PostMapping("/user/updatePassword")
    public ResponseDto updatePassword(@RequestBody UserDTO userDTO) {
        // 先判断旧密码是否正确
        Message<User> byUserId = userClient.getByUserId(ShiroUtil.getUserId());
        // 后期再处理旧密码一致的判断
        if (byUserId.isSuccess() && !byUserId.getData().getPassword().equals(CredentialUtil.md5(userDTO.getPassword(), UserDTO.INIT_SALT_VALUE))) {
            return ResultUtil.fail("旧密码输入错误");
        }
        // 更新用户密码
        userDTO.setId(ShiroUtil.getUserId());
        userDTO.setPassword(CredentialUtil.md5(userDTO.getNewPassword(), UserDTO.INIT_SALT_VALUE));
        Message<Boolean> resetMsg = userClient.resetUserPass(userDTO);
        if (resetMsg.isSuccess()) {

            // 用户下线
            Message<User> clientUser = userClient.getByUserId(userDTO.getId());
            if (clientUser.isSuccess()) {
                ShiroUtil.offline(clientUser.getData().getUsername(), userDTO.getId());
            }
        }
        return ResultUtil.msg(resetMsg);
    }


    /**
     * 忘记密码
     *
     * @param forgetPasswordDTO
     * @return org.fzzn.core.model.msg.ResponseDto
     * @author tian
     * @date 2022-2-24 9:17
     * @updater ljs
     * @updateDate 2022-3-24 10:13:52
     */
    @ApiOperation(value = "忘记密码", notes = "忘记密码")
    @PostMapping("/user/forgetPassword")
    public ResponseDto forgetPassword(@RequestBody ForgetPasswordDTO forgetPasswordDTO) {

        Message<Org> orgDTOMessage = orgClient.getOrgByOrgName(forgetPasswordDTO.getOrgName());
        Org orgDTO = orgDTOMessage.getData();
        if (!orgDTO.getOrgName().equals(forgetPasswordDTO.getOrgName())) {
            return ResultUtil.fail("请输入正确企业信息！");
        }

        // 先判断手机号是否注册
        forgetPasswordDTO.setOrgId(orgDTO.getId());
        User user = userClient.getUserByOrgAndPhoneAndRoleSign(forgetPasswordDTO);
        if (user == null) {
            return ResultUtil.fail(MsgEnum.USERNAME_NOT_FOUND);
        }

        // 更新用户密码
        UserDTO userDTO = user.to(UserDTO.class);
        userDTO.setPassword(CredentialUtil.md5(forgetPasswordDTO.getPassword(), UserDTO.INIT_SALT_VALUE));
        Message<Boolean> resetMsg = userClient.resetUserPass(userDTO);
        if (resetMsg.isSuccess()) {
            return ResultUtil.msg(MsgUtil.success(user.getUsername()));
        }
        return ResultUtil.msg(resetMsg);
    }

    /**
     * 验证验证码
     *
     * @updater ljs
     * @updateDate 2022-4-12 17:13:13
     */
    @ApiOperation(value = "验证手机验证码", notes = "验证手机验证码")
    @PostMapping("/user/checkVerifyCode")
    public ResponseDto checkVerifyCode(@RequestBody ForgetPasswordDTO forgetPasswordDTO) {
        // 先判断手机号是否注册
        User user = userClient.getUserByPhoneAndRoleSign(forgetPasswordDTO);
        if (user == null) {
            return ResultUtil.fail(MsgEnum.USERNAME_NOT_FOUND);
        }

        Message<OrgDTO> orgDTOMessage = orgClient.getOrgById(user.getOrgId());
        OrgDTO orgDTO = orgDTOMessage.getData();
        if (!orgDTO.getOrgName().equals(forgetPasswordDTO.getOrgName())) {
            return ResultUtil.fail("请输入正确企业信息！");
        }

        // 获取缓存中的验证码
        String verifyKey = Constants.PHONE_CAPTCHA_CODE_KEY + forgetPasswordDTO.getPhone();
        String codeByRedis = redisService.get(verifyKey);

        // 判断验证码是否过期
        if (StringUtils.isEmpty(codeByRedis)) {
            return ResultUtil.fail(MsgEnum.VALID_CODE_DEPRECATED);
        }

        // 判断验证码是否正确
        if (!codeByRedis.equals(forgetPasswordDTO.getPhoneCode())) {
            return ResultUtil.fail(MsgEnum.WRONG_VALID_CODE);
        }
        return ResultUtil.SUCCESS;
    }

    /**
     * 验证用户
     *
     * @updater ljs
     * @updateDate 2022-4-12 17:13:13
     */
    @ApiOperation(value = "验证用户是否存在", notes = "验证用户是否存在")
    @PostMapping("/user/checkUser")
    public ResponseDto checkUser(@RequestBody ZappUserDTO zappUserDTO) {
        // 先判断手机号是否注册
        // 查询根据身份证和角色去查询唯一账户
        ForgetPasswordDTO forgetPasswordDTO = new ForgetPasswordDTO();
        forgetPasswordDTO.setPhone(zappUserDTO.getTelephoneNum());
        forgetPasswordDTO.setRoleSign(zappUserDTO.getRoleSign());
        forgetPasswordDTO.setOrgName(zappUserDTO.getLegalName());
        User user = userClient.getUserByPhoneAndRoleSign(forgetPasswordDTO);
        if (user == null) {
            return ResultUtil.fail(MsgEnum.USERNAME_NOT_FOUND);
        }
        return ResultUtil.SUCCESS;
    }

    /**
     * 忘记密码
     *
     * @param zappUserDTO
     * @return org.fzzn.core.model.msg.ResponseDto
     * @author ljs
     * @date 2022-3-24 09:22:48
     */
    @ApiOperation(value = "忘记密码--中招扫码", notes = "忘记密码---中招扫码验证")
    @PostMapping("/user/forgetPasswordByZapp")
    public ResponseDto forgetPasswordByZapp(@RequestBody ZappUserDTO zappUserDTO) {
        // 查询根据身份证和角色去查询唯一账户
        ForgetPasswordDTO forgetPasswordDTO = new ForgetPasswordDTO();
        forgetPasswordDTO.setPhone(zappUserDTO.getTelephoneNum());
        forgetPasswordDTO.setRoleSign(zappUserDTO.getRoleSign());
        User user = userClient.getUserByUnifiedTransactionCodeAndRoleSign(zappUserDTO);
        if (user == null) {
            return ResultUtil.fail(MsgEnum.USERNAME_NOT_FOUND);
        }

        // 更新用户密码
        user.setPassword(CredentialUtil.md5(zappUserDTO.getPassword(), UserDTO.INIT_SALT_VALUE));
        UserDTO userDTO = user.to(UserDTO.class);
        Message<Boolean> resetMsg = userClient.resetUserPass(userDTO);
        if (resetMsg.isSuccess()) {
            return ResultUtil.msg(MsgUtil.success(user.getUsername()));
        }
        return ResultUtil.msg(resetMsg);
    }

    /**
     * Description: 核对中招扫码信息是否与当前登录人一致
     *
     * @param zaphoneNum 中招扫码信息
     * @author: fengbin
     * @date: 2022/2/23 13:51
     * @return: java.lang.Boolean
     */
    @PostMapping("/userConfirmInfo/zappUserConfirmInfo")
    public ResponseDto zappUserConfirmInfo(@RequestBody ZappUserDTO zaphoneNum) {
        LoginUser<Long> loginUser = ShiroUtil.getUser();
        if (null == loginUser) {
            return ResultUtil.fail(MsgEnum.LOGIN_EXPIRE);
        }
        Long offerId = loginUser.getId();
        Message<Boolean> booleanMessage = userClient.zappUserConfirmInfo(zaphoneNum.getTelephoneNum(), offerId);
        return ResultUtil.msg(booleanMessage);
    }

    /**
     * Description: 获取未审核信息的用户信息
     *
     * @param unConfirmUserInfoDTO 用户id
     * @author: ljs
     * @date: 2022-3-25 10:31:10
     * @return:
     */
    @PostMapping("/userConfirmInfo/getUnConfirmUserInfo")
    public ResponseDto getUnConfirmUserInfo(@RequestBody UnConfirmUserInfoDTO unConfirmUserInfoDTO) {
        Long userId = Long.valueOf(unConfirmUserInfoDTO.getId());
        Message<User> userMessage = userClient.getByUserId(userId);
        User user = userMessage.getData();
        if (user == null) {
            return ResultUtil.fail(MsgEnum.USERNAME_NOT_FOUND);
        }
        Message<OrgDTO> orgMessage = orgClient.getOrgById(user.getOrgId());
        OrgDTO orgDTO = orgMessage.getData();
        if (orgDTO == null) {
            return ResultUtil.fail("未查询到企业信息");
        }
        orgDTO.setId(null);
        UnConfirmUserInfoVo unConfirmUserInfoVo = new UnConfirmUserInfoVo();
        BeanUtil.copyProperties(user, unConfirmUserInfoVo);
        BeanUtil.copyProperties(orgDTO, unConfirmUserInfoVo);
        unConfirmUserInfoVo.setReason(user.getReason());
        unConfirmUserInfoVo.setId(user.getId());
        unConfirmUserInfoVo.setCreateTime(user.getCreateTime());
        return ResultUtil.msg(MsgUtil.success(unConfirmUserInfoVo));
    }

    /**
     * Description: 修改审核信息
     *
     * @param reConfirmUserDTO 中招扫码信息
     * @author: ljs
     * @date: 2022-3-25 10:31:10
     * @return:
     */
    @PostMapping("/userConfirmInfo/reCommitConfirm")
    public ResponseDto reCommitConfirm(@RequestBody ReConfirmUserDTO reConfirmUserDTO) {
        reConfirmUserDTO.setPassword(CredentialUtil.md5(reConfirmUserDTO.getPassword(), UserDTO.INIT_SALT_VALUE));
        Message result = userClient.reConfirmUser(reConfirmUserDTO);
        return ResultUtil.msg(result);
    }

    /**
     * 根据用户id查询绑定的第三方ca或者中招
     *
     * @param unConfirmUserInfoDTO
     * @return
     */
    @PostMapping("/userConfirmInfo/listVerifyByUserId")
    public ResponseDto listVerifyByUserId(@RequestBody UnConfirmUserInfoDTO unConfirmUserInfoDTO) {
        if (unConfirmUserInfoDTO == null || unConfirmUserInfoDTO.getId() == null) {
            return ResultUtil.fail(MsgEnum.INCORRECT_PARAM);
        }
        UserVerify userVerify = new UserVerify();
        userVerify.setUserId(Long.valueOf(unConfirmUserInfoDTO.getId()));
        Message<List<UserVerify>> result = userClient.listVerifyByUserId(userVerify);
        return ResultUtil.msg(result);
    }

    /**
     * 更新用户配置属性
     *
     * @param user
     * @return
     */
    @PostMapping("/user/updateUserConfig")
    public ResponseDto<?> updateUserConfig(@RequestBody User user) {
        Long userId = user.getId();
        if (userId == null) {
            return ResultUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        UserConfig config = user.getUserConfig();
        // 数据库中的用户对象
        Message<User> userMessage = userClient.getByUserId(userId);

        // 成功获取到用户对象
        if (userMessage.isSuccess()) {
            User data = userMessage.getData();
            UserConfig userConfig = data.getUserConfig();
            if (userConfig == null) {
                userConfig = new UserConfig();
            }

            // 同步前端参数
            userConfig.update(config);
            data.setUserConfig(userConfig);

            // 执行更新
            UserDTO userDTO = data.to(UserDTO.class);
            Message<Boolean> booleanMessage = userClient.updateUser(userDTO);

            // 执行成功后处理分公司管理员的数据
            if (booleanMessage.isSuccess() && booleanMessage.getData()) {
                Integer roleSign = ShiroUtil.getExtInfoInt("roleSign");
                if(roleSign==null){
                    roleSign = RoleSignEnum.AGENCY.getCode();
                }
                orgClient.handleBranchManager(data.getOrgId(), userConfig, roleSign);
            }

            return ResultUtil.msg(booleanMessage);
        }
        return ResultUtil.msg(userMessage);
    }
}
